package com.fadadianqi.logistics.admin.controller;

import com.fadadianqi.logistics.admin.controller.form.AjaxResult;
import com.fadadianqi.logistics.admin.net.NoSessionConnectedException;
import com.fadadianqi.logistics.admin.net.Session;
import com.fadadianqi.logistics.admin.net.SessionManager;
import com.fadadianqi.commons.JSONProvider;
import com.fadadianqi.commons.PrimaryKeyCreator;
import com.fadadianqi.logistics.customer.model.*;
import com.fadadianqi.logistics.customer.service.CustomerService;
import com.fadadianqi.logistics.customer.service.MsgSendJob;
import com.fadadianqi.logistics.customer.service.MsgSenderService;
import com.yeqiangwei.commons.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
public class MsgSendController {

    private static final Log log = LogFactory.getLog(MsgSendController.class);

    @RequestMapping(value = {"/a/ajax/customer/msgJob/del"}, method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> jobDel(HttpServletRequest request, ModelMap modelMap) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.add("Content-Type", "text/html; charset=utf-8");
        String id = ParamUtils.getString(request, "id", null);
        msgSendJob.delJob(id);
        AjaxResult rs = new AjaxResult(null, Boolean.TRUE, null);
        return new ResponseEntity<String>(JSONProvider.toJSON(rs),
                responseHeaders, HttpStatus.OK);
    }

    @RequestMapping(value = {"/a/ajax/customer/msgJob/delConfirm"}, method = RequestMethod.GET)
    public String jobDelConfirm(HttpServletRequest request, ModelMap modelMap) {
        Session session = SessionManager.getCurrentSession();
        modelMap.put("session", session);
        String id = ParamUtils.getString(request, "id", null);
        MsgJob job = msgSendJob.getMsgJobById(id);
        modelMap.put("msgJob", job);
        return "/admin/customer/msgDelConfirm";
    }

    @RequestMapping(value = {"/a/ajax/customer/msg/do"}, method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> doSomething(HttpServletRequest request,
                                              ModelMap modelMap) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.add("Content-Type", "text/html; charset=utf-8");
        String id = ParamUtils.getString(request, "id", null);
        int act = ParamUtils.getInteger(request, "act", MsgJob.STATUS_PAUSE);
        AjaxResult rs = null;
        try {
            switch (act) {
                case 1:
                    // 执行发送...
                    // 异步任务...
                    msgSenderService.doSendByJobId(id);
                    break;
                case 2: // 继续发送
                    msgSenderService.continueSendByJobId(id);
                    break;
                case 3: // 重新发送
                    msgSenderService.anewSendByJobId(id);
                    break;
                case 4:
                    msgSenderService.cancelByJobId(id);
                    break;
            }
            rs = new AjaxResult(null, Boolean.TRUE, null);
        } catch (InterruptedException e) {
            log.error(e.toString());
            String estr = messageSource.getMessage("remind.error", null, Locale.getDefault());
            rs = new AjaxResult(null, Boolean.FALSE, estr);
        } catch (NoSessionConnectedException e) {
            String estr = messageSource.getMessage("exception.net.required.session", null, Locale.getDefault());
            rs = new AjaxResult(null, Boolean.FALSE, estr);
        }
        return new ResponseEntity<String>(JSONProvider.toJSON(rs),
                responseHeaders, HttpStatus.OK);
    }

    @RequestMapping(value = {"/a/ajax/customer/msg/status"}, method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<String> statusCount(HttpServletRequest request,
                                              ModelMap modelMap) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.add("Content-Type", "text/html; charset=utf-8");
        String id = ParamUtils.getString(request, "id", null);
        int succeed = msgSendJob.countQueueByJobIdAndStatus(id, MsgQueue.STATUS_SUCCEED);
        int already = msgSendJob.countQueueByJobIdAndStatus(id, MsgQueue.STATUS_ALREADY);
        int failed = msgSendJob.countQueueByJobIdAndStatus(id, MsgQueue.STATUS_FAILED);
        int sending = msgSendJob.countQueueByJobIdAndStatus(id, MsgQueue.STATUS_SENDING);
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("succeed", succeed);
        map.put("already", already);
        map.put("failed", failed);
        map.put("sending", sending);
        AjaxResult rs = new AjaxResult(map, Boolean.TRUE, null);
        return new ResponseEntity<String>(JSONProvider.toJSON(rs),
                responseHeaders, HttpStatus.OK);
    }

    @RequestMapping(value = {"/a/ajax/customer/msg/btn"}, method = RequestMethod.GET)
    public String JobButton(HttpServletRequest request, ModelMap modelMap) {
        Session session = SessionManager.getCurrentSession();
        modelMap.put("session", session);
        String id = ParamUtils.getString(request, "id", null);
        MsgJob job = msgSendJob.getMsgJobById(id);
        modelMap.put("msgJob", job);
        return "/admin/customer/msgBtn";
    }

    @RequestMapping(value = {"/a/ajax/customer/msg/client"}, method = RequestMethod.GET)
    public String clientStatus(HttpServletRequest request, ModelMap modelMap) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.add("Content-Type", "text/html; charset=utf-8");
        List<Session> sessionList = SessionManager.getSessionList();
        List<Client> clientList = new ArrayList<MsgSendController.Client>();
        if (ValidatorHelper.isNotEmpty(sessionList)) {
            for (Session sess : sessionList) {
                Client c = new Client();
                c.setSessionId(sess.getId());
                c.setIp((String) sess.getAttribute("ip"));
                clientList.add(c);
            }
        }
        String serverIp = request.getLocalAddr();
        modelMap.put("clientList", clientList);
        modelMap.put("serverIp", serverIp);
        return "/admin/customer/client";
    }

    @RequestMapping(value = {"/a/ajax/customer/townSelector"})
    public String showTownSelector(ModelMap modelMap) {
        List<Town> townList = customerService.findAllTown();
        modelMap.put("townList", townList);
        return "/admin/customer/townSelector";
    }

    @RequestMapping(value = {"/a/customer/msgJobs", "/a/customer/notify"})
    public String showMsgJobs(HttpServletRequest request, ModelMap modelMap) {
        Pagination pagination = new Pagination(request, 20);
        List<MsgJob> jobs = msgSendJob.findAllJobs(pagination);
        modelMap.put("msgJobs", jobs);
        if (ValidatorHelper.isNotEmpty(jobs)) {
            for (MsgJob job : jobs) {
                String id = job.getId();
                if (job.getStatus() == MsgJob.STATUS_OK) {
                    int sending = msgSendJob.countQueueByJobIdAndStatus(id, MsgQueue.STATUS_SENDING);
                    if (sending == 0) {
                        // 如果没有正在发送中的消息，则表示任务已完成
                        job.setStatus(MsgJob.STATUS_OK);
                        msgSendJob.updateJob(job);
                    }
                }
            }
        }
        pagination.setTotal(msgSendJob.countAllJobs());
        PaginationHelper.setAttribute(request, pagination);
        return "/admin/customer/msgJobs";
    }

    @RequestMapping(value = {"/a/customer/msgJob/details",
            "/a/customer/msgJob"})
    public String showMsgJob(HttpServletRequest request, ModelMap modelMap) {
        String id = ParamUtils.getString(request, "id", null);
        MsgJob job = msgSendJob.getMsgJobById(id);
        modelMap.put("msgJob", job);

        Pagination pagination = new Pagination(request, 20);
        List<MsgQueue> queueList = msgSendJob.findAllQueue(id, pagination);
        List<MsgQueueVO> voList = new ArrayList<MsgQueueVO>();
        if (ValidatorHelper.isNotEmpty(queueList)) {
            for (MsgQueue mq : queueList) {
                MsgQueueVO vo = new MsgQueueVO();
                BeanUtils.copyProperties(mq, vo);
                Customer customer = customerService.getById(mq.getCustomerId());
                vo.setCustomer(customer);
                if (customer != null) {
                    vo.setTown(customerService.getTownById(customer.getTownId()));
                    vo.setVillage(customerService.getVillageById(customer
                            .getVillageId()));
                }
                voList.add(vo);
            }
        }
        modelMap.put("queueList", voList);
        pagination.setTotal(msgSendJob.countQueueByJobId(id));
        Map<String, Object> eles = new HashMap<String, Object>();
        eles.put("id", id);
        pagination.setElements(eles);
        PaginationHelper.setAttribute(request, pagination);
        return "/admin/customer/msgJob";
    }

    @RequestMapping(value = {"/a/ajax/customer/msgJobs/save"}, method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> ajaxSaveJob(HttpServletRequest request,
                                              ModelMap modelMap) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.add("Content-Type", "text/html; charset=utf-8");
        String _townIds = ParamUtils.getString(request, "townIds", null);
        String content = ParamUtils.getString(request, "content", null);
        String name = ParamUtils.getString(request, "name", null);
        String _endTime = ParamUtils.getString(request, "endTime", null);
        String endTime = _endTime + " 00:00:00";
        if (ValidatorHelper.isNotEmpty(_townIds)
                && ValidatorHelper.isNotEmpty(name)
                && ValidatorHelper.isNotEmpty(content)) {
            String[] townIds = _townIds.split(",");
            MsgJob job = new MsgJob();
            job.setAddTime(new Date());
            job.setContent(content);
            job.setFailed(0);
            job.setId(PrimaryKeyCreator.create());
            job.setName(name);
            job.setStatus(MsgJob.STATUS_ALREADY);
            job.setSucceed(0);
            job.setTotal(0);
            SimpleDateFormat sdf = new SimpleDateFormat(DateTimeUtils.FMT_YYYY_MM_DD_HH_MM_SS);
            try {
                job.setEndTime(sdf.parse(endTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            msgSendJob.sendToTown(townIds, job);
        }
        AjaxResult rs = new AjaxResult(null, Boolean.TRUE, null);
        return new ResponseEntity<String>(JSONProvider.toJSON(rs),
                responseHeaders, HttpStatus.OK);
    }

    @RequestMapping(value = {"/a/customer/msgJobs/create"})
    public String showForm(HttpServletRequest request, ModelMap modelMap) {
        long end = DateTimeUtils.nDaysAfterTime(7);
        String endDate = DateTimeUtils.format(end, DateTimeUtils.FMT_YYYY_MM_DD);
        modelMap.put("endDate", endDate);
        return "/admin/customer/msgJobsForm";
    }

    @Autowired
    private MsgSendJob msgSendJob;

    @Autowired
    private MsgSenderService msgSenderService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private MessageSource messageSource;

    public class Client implements java.io.Serializable {
        /**
         *
         */
        private static final long serialVersionUID = 7569522333043284001L;

        private String sessionId;
        private String ip;

        public String getSessionId() {
            return sessionId;
        }

        public void setSessionId(String sessionId) {
            this.sessionId = sessionId;
        }

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }
    }

    public static class MsgQueueVO extends MsgQueue {
        /**
         *
         */
        private static final long serialVersionUID = 4716413411584750493L;

        private Customer customer;
        private Town town;
        private Village village;

        public Town getTown() {
            return town;
        }

        public void setTown(Town town) {
            this.town = town;
        }

        public Village getVillage() {
            return village;
        }

        public void setVillage(Village village) {
            this.village = village;
        }

        public Customer getCustomer() {
            return customer;
        }

        public void setCustomer(Customer customer) {
            this.customer = customer;
        }
    }
}
